﻿namespace ch05.binary
{
    public class OpNames
    {
        private readonly string[] _opNameArr = new string[256];
        private static OpNames _opNames;

        public static string[] GetOpNameArr()
        {
            _opNames ??= new OpNames();
            return _opNames._opNameArr;
        }

        private OpNames()
        {
            _opNameArr[OpCodes.Unreachable] = "unreachable";
            _opNameArr[OpCodes.Nop] = "nop";
            _opNameArr[OpCodes.Block] = "block";
            _opNameArr[OpCodes.Loop] = "loop";
            _opNameArr[OpCodes.If] = "if";
            _opNameArr[OpCodes.Else] = "else";
            _opNameArr[OpCodes.End] = "end";
            _opNameArr[OpCodes.Br] = "br";
            _opNameArr[OpCodes.BrIf] = "br_if";
            _opNameArr[OpCodes.BrTable] = "br_table";
            _opNameArr[OpCodes.Return] = "return";
            _opNameArr[OpCodes.Call] = "call";
            _opNameArr[OpCodes.CallIndirect] = "call_indirect";
            _opNameArr[OpCodes.Drop] = "drop";
            _opNameArr[OpCodes.Select] = "select";
            _opNameArr[OpCodes.LocalGet] = "local.get";
            _opNameArr[OpCodes.LocalSet] = "local.set";
            _opNameArr[OpCodes.LocalTee] = "local.tee";
            _opNameArr[OpCodes.GlobalGet] = "global.get";
            _opNameArr[OpCodes.GlobalSet] = "global.set";
            _opNameArr[OpCodes.I32Load] = "i32.load";
            _opNameArr[OpCodes.I64Load] = "i64.load";
            _opNameArr[OpCodes.F32Load] = "f32.load";
            _opNameArr[OpCodes.F64Load] = "f64.load";
            _opNameArr[OpCodes.I32Load8S] = "i32.load8_s";
            _opNameArr[OpCodes.I32Load8U] = "i32.load8_u";
            _opNameArr[OpCodes.I32Load16S] = "i32.load16_s";
            _opNameArr[OpCodes.I32Load16U] = "i32.load16_u";
            _opNameArr[OpCodes.I64Load8S] = "i64.load8_s";
            _opNameArr[OpCodes.I64Load8U] = "i64.load8_u";
            _opNameArr[OpCodes.I64Load16S] = "i64.load16_s";
            _opNameArr[OpCodes.I64Load16U] = "i64.load16_u";
            _opNameArr[OpCodes.I64Load32S] = "i64.load32_s";
            _opNameArr[OpCodes.I64Load32U] = "i64.load32_u";
            _opNameArr[OpCodes.I32Store] = "i32.store";
            _opNameArr[OpCodes.I64Store] = "i64.store";
            _opNameArr[OpCodes.F32Store] = "f32.store";
            _opNameArr[OpCodes.F64Store] = "f64.store";
            _opNameArr[OpCodes.I32Store8] = "i32.store8";
            _opNameArr[OpCodes.I32Store16] = "i32.store16";
            _opNameArr[OpCodes.I64Store8] = "i64.store8";
            _opNameArr[OpCodes.I64Store16] = "i64.store16";
            _opNameArr[OpCodes.I64Store32] = "i64.store32";
            _opNameArr[OpCodes.MemorySize] = "memory.size";
            _opNameArr[OpCodes.MemoryGrow] = "memory.grow";
            _opNameArr[OpCodes.I32Const] = "i32.const";
            _opNameArr[OpCodes.I64Const] = "i64.const";
            _opNameArr[OpCodes.F32Const] = "f32.const";
            _opNameArr[OpCodes.F64Const] = "f64.const";
            _opNameArr[OpCodes.I32Eqz] = "i32.eqz";
            _opNameArr[OpCodes.I32Eq] = "i32.eq";
            _opNameArr[OpCodes.I32Ne] = "i32.ne";
            _opNameArr[OpCodes.I32LtS] = "i32.lt_s";
            _opNameArr[OpCodes.I32LtU] = "i32.lt_u";
            _opNameArr[OpCodes.I32GtS] = "i32.gt_s";
            _opNameArr[OpCodes.I32GtU] = "i32.gt_u";
            _opNameArr[OpCodes.I32LeS] = "i32.le_s";
            _opNameArr[OpCodes.I32LeU] = "i32.le_u";
            _opNameArr[OpCodes.I32GeS] = "i32.ge_s";
            _opNameArr[OpCodes.I32GeU] = "i32.ge_u";
            _opNameArr[OpCodes.I64Eqz] = "i64.eqz";
            _opNameArr[OpCodes.I64Eq] = "i64.eq";
            _opNameArr[OpCodes.I64Ne] = "i64.ne";
            _opNameArr[OpCodes.I64LtS] = "i64.lt_s";
            _opNameArr[OpCodes.I64LtU] = "i64.lt_u";
            _opNameArr[OpCodes.I64GtS] = "i64.gt_s";
            _opNameArr[OpCodes.I64GtU] = "i64.gt_u";
            _opNameArr[OpCodes.I64LeS] = "i64.le_s";
            _opNameArr[OpCodes.I64LeU] = "i64.le_u";
            _opNameArr[OpCodes.I64GeS] = "i64.ge_s";
            _opNameArr[OpCodes.I64GeU] = "i64.ge_u";
            _opNameArr[OpCodes.F32Eq] = "f32.eq";
            _opNameArr[OpCodes.F32Ne] = "f32.ne";
            _opNameArr[OpCodes.F32Lt] = "f32.lt";
            _opNameArr[OpCodes.F32Gt] = "f32.gt";
            _opNameArr[OpCodes.F32Le] = "f32.le";
            _opNameArr[OpCodes.F32Ge] = "f32.ge";
            _opNameArr[OpCodes.F64Eq] = "f64.eq";
            _opNameArr[OpCodes.F64Ne] = "f64.ne";
            _opNameArr[OpCodes.F64Lt] = "f64.lt";
            _opNameArr[OpCodes.F64Gt] = "f64.gt";
            _opNameArr[OpCodes.F64Le] = "f64.le";
            _opNameArr[OpCodes.F64Ge] = "f64.ge";
            _opNameArr[OpCodes.I32Clz] = "i32.clz";
            _opNameArr[OpCodes.I32Ctz] = "i32.ctz";
            _opNameArr[OpCodes.I32PopCnt] = "i32.popcnt";
            _opNameArr[OpCodes.I32Add] = "i32.add";
            _opNameArr[OpCodes.I32Sub] = "i32.sub";
            _opNameArr[OpCodes.I32Mul] = "i32.mul";
            _opNameArr[OpCodes.I32DivS] = "i32.div_s";
            _opNameArr[OpCodes.I32DivU] = "i32.div_u";
            _opNameArr[OpCodes.I32RemS] = "i32.rem_s";
            _opNameArr[OpCodes.I32RemU] = "i32.rem_u";
            _opNameArr[OpCodes.I32And] = "i32.and";
            _opNameArr[OpCodes.I32Or] = "i32.or";
            _opNameArr[OpCodes.I32Xor] = "i32.xor";
            _opNameArr[OpCodes.I32Shl] = "i32.shl";
            _opNameArr[OpCodes.I32ShrS] = "i32.shr_s";
            _opNameArr[OpCodes.I32ShrU] = "i32.shr_u";
            _opNameArr[OpCodes.I32Rotl] = "i32.rotl";
            _opNameArr[OpCodes.I32Rotr] = "i32.rotr";
            _opNameArr[OpCodes.I64Clz] = "i64.clz";
            _opNameArr[OpCodes.I64Ctz] = "i64.ctz";
            _opNameArr[OpCodes.I64PopCnt] = "i64.popcnt";
            _opNameArr[OpCodes.I64Add] = "i64.add";
            _opNameArr[OpCodes.I64Sub] = "i64.sub";
            _opNameArr[OpCodes.I64Mul] = "i64.mul";
            _opNameArr[OpCodes.I64DivS] = "i64.div_s";
            _opNameArr[OpCodes.I64DivU] = "i64.div_u";
            _opNameArr[OpCodes.I64RemS] = "i64.rem_s";
            _opNameArr[OpCodes.I64RemU] = "i64.rem_u";
            _opNameArr[OpCodes.I64And] = "i64.and";
            _opNameArr[OpCodes.I64Or] = "i64.or";
            _opNameArr[OpCodes.I64Xor] = "i64.xor";
            _opNameArr[OpCodes.I64Shl] = "i64.shl";
            _opNameArr[OpCodes.I64ShrS] = "i64.shr_s";
            _opNameArr[OpCodes.I64ShrU] = "i64.shr_u";
            _opNameArr[OpCodes.I64Rotl] = "i64.rotl";
            _opNameArr[OpCodes.I64Rotr] = "i64.rotr";
            _opNameArr[OpCodes.F32Abs] = "f32.abs";
            _opNameArr[OpCodes.F32Neg] = "f32.neg";
            _opNameArr[OpCodes.F32Ceil] = "f32.ceil";
            _opNameArr[OpCodes.F32Floor] = "f32.floor";
            _opNameArr[OpCodes.F32Trunc] = "f32.trunc";
            _opNameArr[OpCodes.F32Nearest] = "f32.nearest";
            _opNameArr[OpCodes.F32Sqrt] = "f32.sqrt";
            _opNameArr[OpCodes.F32Add] = "f32.add";
            _opNameArr[OpCodes.F32Sub] = "f32.sub";
            _opNameArr[OpCodes.F32Mul] = "f32.mul";
            _opNameArr[OpCodes.F32Div] = "f32.div";
            _opNameArr[OpCodes.F32Min] = "f32.min";
            _opNameArr[OpCodes.F32Max] = "f32.max";
            _opNameArr[OpCodes.F32CopySign] = "f32.copysign";
            _opNameArr[OpCodes.F64Abs] = "f64.abs";
            _opNameArr[OpCodes.F64Neg] = "f64.neg";
            _opNameArr[OpCodes.F64Ceil] = "f64.ceil";
            _opNameArr[OpCodes.F64Floor] = "f64.floor";
            _opNameArr[OpCodes.F64Trunc] = "f64.trunc";
            _opNameArr[OpCodes.F64Nearest] = "f64.nearest";
            _opNameArr[OpCodes.F64Sqrt] = "f64.sqrt";
            _opNameArr[OpCodes.F64Add] = "f64.add";
            _opNameArr[OpCodes.F64Sub] = "f64.sub";
            _opNameArr[OpCodes.F64Mul] = "f64.mul";
            _opNameArr[OpCodes.F64Div] = "f64.div";
            _opNameArr[OpCodes.F64Min] = "f64.min";
            _opNameArr[OpCodes.F64Max] = "f64.max";
            _opNameArr[OpCodes.F64CopySign] = "f64.copysign";
            _opNameArr[OpCodes.I32WrapI64] = "i32.wrap_i64";
            _opNameArr[OpCodes.I32TruncF32S] = "i32.trunc_f32_s";
            _opNameArr[OpCodes.I32TruncF32U] = "i32.trunc_f32_u";
            _opNameArr[OpCodes.I32TruncF64S] = "i32.trunc_f64_s";
            _opNameArr[OpCodes.I32TruncF64U] = "i32.trunc_f64_u";
            _opNameArr[OpCodes.I64ExtendI32S] = "i64.extend_i32_s";
            _opNameArr[OpCodes.I64ExtendI32U] = "i64.extend_i32_u";
            _opNameArr[OpCodes.I64TruncF32S] = "i64.trunc_f32_s";
            _opNameArr[OpCodes.I64TruncF32U] = "i64.trunc_f32_u";
            _opNameArr[OpCodes.I64TruncF64S] = "i64.trunc_f64_s";
            _opNameArr[OpCodes.I64TruncF64U] = "i64.trunc_f64_u";
            _opNameArr[OpCodes.F32ConvertI32S] = "f32.convert_i32_s";
            _opNameArr[OpCodes.F32ConvertI32U] = "f32.convert_i32_u";
            _opNameArr[OpCodes.F32ConvertI64S] = "f32.convert_i64_s";
            _opNameArr[OpCodes.F32ConvertI64U] = "f32.convert_i64_u";
            _opNameArr[OpCodes.F32DemoteF64] = "f32.demote_f64";
            _opNameArr[OpCodes.F64ConvertI32S] = "f64.convert_i32_s";
            _opNameArr[OpCodes.F64ConvertI32U] = "f64.convert_i32_u";
            _opNameArr[OpCodes.F64ConvertI64S] = "f64.convert_i64_s";
            _opNameArr[OpCodes.F64ConvertI64U] = "f64.convert_i64_u";
            _opNameArr[OpCodes.F64PromoteF32] = "f64.promote_f32";
            _opNameArr[OpCodes.I32ReinterpretF32] = "i32.reinterpret_f32";
            _opNameArr[OpCodes.I64ReinterpretF64] = "i64.reinterpret_f64";
            _opNameArr[OpCodes.F32ReinterpretI32] = "f32.reinterpret_i32";
            _opNameArr[OpCodes.F64ReinterpretI64] = "f64.reinterpret_i64";
            _opNameArr[OpCodes.I32Extend8S] = "i32.extend8_s";
            _opNameArr[OpCodes.I32Extend16S] = "i32.extend16_s";
            _opNameArr[OpCodes.I64Extend8S] = "i64.extend8_s";
            _opNameArr[OpCodes.I64Extend16S] = "i64.extend16_s";
            _opNameArr[OpCodes.I64Extend32S] = "i64.extend32_s";
            _opNameArr[OpCodes.TruncSat] = "trunc_sat";
        }
    }
}